package release_system

import (
	"github.com/fsnotify/fsnotify"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"k8s-platform/config"
	"k8s-platform/model"
	"k8s-platform/service/release_system"
	"net/http"
	"os"
	"path/filepath"
	"strings"
)

var K8sDeployHandler k8sDeployHandler

// K8sDeployHandler 接口层处理器
type k8sDeployHandler struct{}

// 写入k8s安装环境配置
func (*k8sDeployHandler) Create_Deploy_Config(c *gin.Context) {
	config := &model.K8sDeployConfig{}

	// 1. 参数绑定失败：返回 400 Bad Request
	if err := c.ShouldBindJSON(config); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 90400,
			"msg":  "参数格式错误：" + err.Error(),
			"data": nil,
		})
		return
	}

	// 2. 数据库保存失败：返回 500 Internal Server Error
	if err := release_system.K8sDeployHandler.Create_Deploy_Config(config); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 90500,
			"msg":  "配置保存失败：" + err.Error(),
			"data": nil,
		})
		return
	}

	// 3. 全部成功：返回 200 OK
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"msg":  "K8s部署配置创建成功",
		"data": nil,
	})
}

// 部署k8s
func (*k8sDeployHandler) Ansible_init(c *gin.Context) {
	config := &model.K8sDeployConfig{}
	if err := c.ShouldBindJSON(config); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 90400,
			"msg":  "请求参数解析失败：" + err.Error(),
			"data": nil,
		})
		return
	}

	if err := release_system.K8sDeployHandler.Ansible_init(config); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 90500,
			"msg":  "生成配置失败：" + err.Error(),
			"data": nil,
		})
		return
	}
	// 3. 全部成功：返回 200 OK
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"msg":  "K8s部署配置创建成功",
		"data": nil,
	})
}

// GenerateScriptHandler 生成K8s部署脚本的HTTP接口
func (*k8sDeployHandler) GenerateAutomationScript_Install(c *gin.Context) {
	// 1. 绑定前端传入的 K8sDeployConfig 参数（JSON格式）
	var req model.K8sDeployConfig
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  "参数格式错误：" + err.Error(),
			"data": nil,
		})
		return
	}

	// 2. 调用服务生成脚本
	if err := release_system.GenerateAutomationScript_Install(req); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "生成脚本失败：" + err.Error(),
			"data": nil,
		})
		return
	}

	// 3. 返回成功响应（包含脚本路径）
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"msg":  "脚本生成成功开始部署",
		"data": nil,
	})
}

// 查询k8s安装列表
func (*k8sDeployHandler) GetInstallK8s(c *gin.Context) {
	data, err := release_system.K8sDeployHandler.K8s_install_List()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 90500,
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"msg":  "查询K8s_install列表成功",
		"data": data,
	})
}

// 编辑k8s安装config文件
func (*k8sDeployHandler) Update_Deploy_Config(c *gin.Context) {
	config := &model.K8sDeployConfig{}
	if err := c.ShouldBindJSON(config); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 90400,
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	if err := release_system.K8sDeployHandler.Update_Deploy_Config(config); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 90500,
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"msg":  "K8s部署配置创建成功",
		"data": nil,
	})
}

// 删除配置
type DeleteDeployConfigRequest struct {
	ID int64 `json:"id" binding:"required,gt=0"` // 只需要id，无需required（前端必传即可）
}

func (*k8sDeployHandler) Delete_Deploy_Config(c *gin.Context) {
	// 使用新结构体接收参数，避免原结构体的required校验
	Delete := &DeleteDeployConfigRequest{}
	if err := c.ShouldBindJSON(Delete); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 90400,
			"msg":  "参数错误：" + err.Error(),
			"data": nil,
		})
		return
	}

	if err := release_system.K8sDeployHandler.Delete_Deploy_Config(Delete.ID); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 90500,
			"msg":  err.Error(),
			"data": nil,
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 0,
		"msg":  "删除K8sDeployConfig成功",
		"data": nil,
	})
}

//k8s安装部署日志ws协议实时查看

// 全局升级器（允许跨域）
var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

// LogStream 处理 WebSocket 日志流请求
func (*k8sDeployHandler) LogStream(c *gin.Context) {
	// 1. 从路径参数获取 k8sname（集群名称）
	k8sName := c.Param("k8sname")
	if k8sName == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  "k8sname不能为空",
		})
		return
	}

	// 2. 升级 HTTP 连接为 WebSocket
	ws, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "WebSocket升级失败: " + err.Error(),
		})
		return
	}
	defer ws.Close()

	// 3. 定位该集群对应的日志文件
	logDir := config.K8s_install_logs // 建议在配置文件中定义日志目录（如 "./logs"）
	files, err := os.ReadDir(logDir)
	if err != nil {
		ws.WriteJSON(gin.H{"code": 500, "msg": "读取日志目录失败: " + err.Error()})
		return
	}

	// 查找最新的日志文件（匹配 {k8sname}_*.log 格式）
	var targetFile string
	for _, file := range files {
		if !file.IsDir() &&
			strings.HasPrefix(file.Name(), k8sName+"_") &&
			strings.HasSuffix(file.Name(), ".log") {
			targetFile = filepath.Join(logDir, file.Name())
		}
	}
	if targetFile == "" {
		ws.WriteJSON(gin.H{"code": 404, "msg": "未找到日志文件"})
		return
	}

	// 4. 先推送历史日志（文件当前所有内容）
	content, err := os.ReadFile(targetFile)
	if err != nil {
		ws.WriteJSON(gin.H{"code": 500, "msg": "读取历史日志失败: " + err.Error()})
		return
	}
	if err := ws.WriteMessage(websocket.TextMessage, content); err != nil {
		return
	}

	// 5. 监听日志文件变化，实时推送新增内容
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		ws.WriteJSON(gin.H{"code": 500, "msg": "创建文件监听器失败: " + err.Error()})
		return
	}
	defer watcher.Close()

	// 添加监听目标文件
	if err := watcher.Add(targetFile); err != nil {
		ws.WriteJSON(gin.H{"code": 500, "msg": "监听日志文件失败: " + err.Error()})
		return
	}

	// 循环处理文件变化事件
	for {
		select {
		case event, ok := <-watcher.Events:
			if !ok {
				return
			}
			// 仅处理文件写入事件（内容新增）
			if event.Op&fsnotify.Write == fsnotify.Write {
				// 读取最新内容（生产环境可优化为增量读取）
				newContent, err := os.ReadFile(targetFile)
				if err != nil {
					ws.WriteJSON(gin.H{"code": 500, "msg": "读取新增日志失败: " + err.Error()})
					continue
				}
				// 推送给前端
				if err := ws.WriteMessage(websocket.TextMessage, newContent); err != nil {
					return // 前端断开连接时退出
				}
			}
		case err, ok := <-watcher.Errors:
			if !ok {
				return
			}
			ws.WriteJSON(gin.H{"code": 500, "msg": "监听错误: " + err.Error()})
		}
	}
}
